﻿using ACC.Business;
using ACC.Business.Process;
using ACC.Business.Stn;
using ACC.Business.Utils;
using ACC.Data;
using ACC.Data.ACCLog;
using ACC.Data.Comm;
using ACC.Data.Entities.Common;
using ACC.Data.Entities.Mes;
using ACC.Data.Line;
using ACC.Device;
using ACC.Device.Client;
using ACC.Device.PLC.Siemens;
using ACC.LineDevice.KukaPack;
using ACC.Interface.Extensions;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading;

namespace Script
{
    /// <summary>
    /// 模组堆叠  
    /// OP L1M03020 STATION L1M13021, L1M13022  L1M23021  L1M23022
    /// </summary>
    public class L1M03020 : StnProcessPL02_JT
    {
        string Zone = string.Empty;

        public L1M03020(StnRunningData data)
            : base(data)
        {
            IsACCReport = true;
            // TO-DO:？？绑定到底是在Load还是Unload ？
            _data.ProcessUnitIDWhenLoad = false;
            // 虽然条码里放了电芯段的托盘号，但是这里不用
            IsPalletRelationSN = false;
        }

        //protected override void CreateBusinessLogic()
        //{
        //    base.CreateBusinessLogic();

        //    //_loadProcess = new LoadFromTest(_data);
        //}

        protected override ACCDevice CreateDevice()
        {
            ACCDevice dev = base.CreateDevice();
            if (kukaSiemensDev != null)
            {
                switch (_data.StnCfg.Name)
                {
                    case "L1M13021":
                    case "L1M23021":
                        {
                            kukaSiemensDev.DB190_Offset = 16000;
                            kukaSiemensDev.LoadBarcodeCount = 21;
                            kukaSiemensDev.UnloadBarcodeCount = 22; // Unload 时从写入的条码读取，多一个托盘号
                        }
                        break;
                    case "L1M13022":
                    case "L1M23022":
                        {
                            kukaSiemensDev.DB190_Offset = 22000;
                            kukaSiemensDev.LoadBarcodeCount = 21;
                            kukaSiemensDev.UnloadBarcodeCount = 22;
                        }
                        break;
                }

                if (_data.StnCfg.Name.StartsWith("L1M1")) // 模组1区
                    Zone = "2";
                else if (_data.StnCfg.Name.StartsWith("L1M2")) // 模组2区
                    Zone = "3";

                kukaSiemensDev.DB190 = 800;
                kukaSiemensDev.DB192 = 80;
                kukaSiemensDev.DB192_PLC_Offset = 1250;
                kukaSiemensDev.DB193 = 800;
                kukaSiemensDev.DB193_PLC_Offset = (ushort)(kukaSiemensDev.DB190_Offset + 34);
                kukaSiemensDev.DB193_ACC_Offset = (ushort)(kukaSiemensDev.DB190_Offset + 68);
                kukaSiemensDev.DB194 = 800;
                kukaSiemensDev.DB194_PLC_Offset = (ushort)(kukaSiemensDev.DB190_Offset + 2);
                kukaSiemensDev.DB194_PLC_Data_Offset = (ushort)(kukaSiemensDev.DB190_Offset + 1262);

                kukaSiemensDev.BarcodeLength = 30;
                // TO-DO:
                kukaSiemensDev.Material_COMM_Offset = 1252; // 上下料信号位偏移量
            }

            return dev;

        }

        BomItemCfg bomItemCfgJT = null;
        BomItemCfg bomItemCfgDx = null;
        BomItemCfg bomItemCfgDb = null;
        BomItemCfg bomItemCfgJyp = null;

        /// <summary>
        /// 换型时读取零件需要的个数，不要再ReadLoadParam中做，只要换型时候一次就行
        /// </summary>
        /// <param name="newpartno"></param>
        public override void ChangePartNo(RuningPartNo newpartno)
        {
            base.ChangePartNo(newpartno);

            if (newpartno != null)
            {
                bomItemCfgJT = _data.PartNo.BomCfg.GetBomItemCfgByIDName("模组基体").Clone();
                bomItemCfgDx = _data.PartNo.BomCfg.GetBomItemCfgByIDName("电芯").Clone();
                bomItemCfgDb = _data.PartNo.BomCfg.GetBomItemCfgByIDName("端板").Clone();
                bomItemCfgJyp = _data.PartNo.BomCfg.GetBomItemCfgByIDName("绝缘片").Clone();

                bomItemCfgDx.QtyPer = GetBomItemQty("电芯");//设定一个模组需要的电芯个数
                bomItemCfgDb.QtyPer = GetBomItemQty("端板");
                bomItemCfgJyp.QtyPer = GetBomItemQty("绝缘片");
            }
        }

        public override ACCCode ReadLoadParam(ACCDevice dev, out ACCDevice.LoadParam param)
        {
            //_data.Components = new BomItemCfg[] { bomItemCfgJyp, bomItemCfgDb, bomItemCfgDx };
            _data.Components = new BomItemCfg[] { bomItemCfgJT, bomItemCfgDb, bomItemCfgJyp, bomItemCfgDx };
            ACCCode rs = base.ReadLoadParam(dev, out param);
            if (rs == ACCCode.ACCOK)
            {
                //var barcodes = new string[] { param.UnitSN };
                //var v = barcodes.Concat(param.ComponentSN);

                // TO-DO: 生成模组基体码
                _data.PartNo.Variables["ZONE"] = string.IsNullOrEmpty(Zone) ? "2" : Zone;
                // [PARTNO][LINE,SITE][CY][M][D][PARTNO,ZONE][COUNTER,JTSN,6]
                param.UnitSN = PartTypeTagProcess.GetPartTypeTagValue(_data.PartNo.BomCfg, "JTSN", logger).Replace("-", "");
                param.UnitSN = param.UnitSN.Replace("?", Zone);
                //param.ComponentSN = v.ToArray();
                //_data.Components = new BomItemCfg[] { bomItemCfgJT, bomItemCfgJyp, bomItemCfgDb, bomItemCfgDx };
            }

            return rs;
        }

        /// <summary>
        /// </summary>
        /// <param name="dev"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override ACCCode SendLoadResult(ACCDevice dev, ACCDevice.LoadResult result)
        {
            if (result.ErrorCode == ACCCode.ACCOK)
            {
                //发送模组基体码给PLC,由PLC负责激光打码
                result.ErrorCode = SendBarcodeToPlc(new string[] { _data.LastLoadUnit.UnitSN }, kukaSiemensDev.DB190_Offset + 2, 30); //16002 22002
            }

            return base.SendLoadResult(dev, result);
        }

        public override ACCCode ReadUnloadParam(ACCDevice dev, out ACCDevice.UnloadParam param)
        {
            ACCCode rs = base.ReadUnloadParam(dev, out param);
            //_data.Components = new BomItemCfg[] { _data.PartNo.BomCfg.GetBomItemCfgByIDName("模组基体"), };
            // TO-DO: _data.LastLoadUnit.UnitSN 为什么? Load 写入后，Unload应该会读取到模组码
            //param.UnitSN = _data.LastLoadUnit.UnitSN;
            if (param.ComponentSN.Length > 1)
            {
                // 零件条码第一个位置是托盘号，要去掉
                var v = param.ComponentSN.ToList();
                v.RemoveAt(0);
                param.ComponentSN = v.ToArray();                
            }

            return rs;
        }

        public override ACCCode SendUnloadResult(ACCDevice dev, ACCDevice.UnloadResult result)
        {
            if (result.ErrorCode == ACCCode.ACCOK && _data.LastUnloadUnit != null)
            {
                // 记录电芯的位置，放到UnitID_TAG里
                int index = 0;
                foreach (string cell in _unloadProcess._unloadParam.ComponentSN)
                {
                    var unitid = _data.LastUnloadUnit.GetUnitIDsByIDValue(cell);
                    if (unitid != null && unitid.Length > 0 && unitid[0].IDName == "电芯")
                    {
                        ++index;
                        unitid[0].SetTagValue(_lineData, "位置", index, logger);
                    }
                }
            }

            return base.SendUnloadResult(dev, result);
        }

        /// <summary>
        /// 把电芯在模组中安装的位置信息上传给MES，位置信息按照PLC给的电芯顺序
        /// </summary>
        /// <param name="stnData"></param>
        /// <returns></returns>
        public override List<SCADAMaterialData> GetMaterialData(StnRunningData stnData)
        {
            var materials = new List<SCADAMaterialData>();
            try
            {
                var opBomCfg = stnData.PartNo == null ? null : stnData.PartNo.BomCfg.BomItemCfg[_data.StnCfg.OPCfg];
                var compSet = stnData.CurrentCompSets[stnData.PartNo.BomCfg.PartNo];
                if (compSet != null)
                {
                    foreach (var comp in compSet.Items)
                    {
                        materials.Add(new SCADAMaterialData()
                        {
                            ctrl_code = string.IsNullOrEmpty(comp.Value.BomItem.IDName) ? (uint)1 : (uint)2, //1-批次件，2-序列件，3-标准件
                            item_code = comp.Value.BomItem.ItemPartNo,
                            item_name = comp.Value.BomItem.Desc,
                            material_unit = "",
                            part_batchsn = comp.Value.LotItem == null ? GetLastLotTrackItem(stnData.StnCfg.LineCfg.Line, stnData.StnCfg.OPCfg.OP, comp.Value.BomItem.ItemPartNo).Lot : comp.Value.LotItem.Lot,
                            part_sn = comp.Value.LotItem == null ? "" : comp.Value.LotItem.Reserved,
                            //qty = Convert.ToUInt32(comp.Value.LotItem.Qty)
                            //qty = Convert.ToUInt32(comp.Value.LotItem.QtyStart) - Convert.ToUInt32(comp.Value.LotItem.Qty),
                            qty = Convert.ToDecimal(opBomCfg == null ? 0 : opBomCfg.BomItem[comp.Value.BomItem.ItemPartNo].QtyPer),
                        });
                    }
                }

                List<WIPUnitID> UnitIDs = stnData.LastUnloadUnit.UnitIDs;
                if (UnitIDs != null)
                {
                    foreach (var unitID in UnitIDs)
                    {
                        try
                        {
                            if (unitID.IDValue == stnData.LastUnloadUnit.UnitSN)
                            {
                                continue;
                            }

                            var bomItemCfg = opBomCfg == null ? null : opBomCfg.BomItem.Values.FirstOrDefault(c => c.ItemPartNo == unitID.ItemPartNo);
                            if (bomItemCfg == null) // 非本OP的系列件，不用报工
                            {
                                continue;
                            }

                            materials.Add(new SCADAMaterialData()
                            {
                                ctrl_code = 2, //1-批次件，2-序列件，3-标准件
                                item_code = bomItemCfg.ItemPartNo,
                                item_name = bomItemCfg.DescLocal,
                                material_unit = bomItemCfg.UM,
                                part_batchsn = "",
                                part_sn = unitID.IDValue,
                                position = unitID.GetTagValue("位置") == null ? string.Empty : unitID.GetTagValue("位置").ToString(),
                                qty = 1
                            });
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex.Message + "\r\n" + ex.StackTrace);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message + "\r\n" + ex.StackTrace);
            }

            return materials;
        }
    }
}
